home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / modelers / geomview / source.lha / Geomview / src / lib / gprim / sphere / spheremisc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-19  |  5.0 KB  |  190 lines

  1. #include <stdio.h>
  2. #include <math.h>
  3. #include "geom.h"
  4. #include "geomclass.h"
  5. #include "transform.h"
  6. #include "sphereP.h"
  7. #include "hpoint3.h"
  8.  
  9. #ifndef FUDGE
  10. #define FUDGE    1e-6
  11. #endif
  12.  
  13. void SphereMinMax(Sphere *sphere, HPoint3 *min, HPoint3 *max) 
  14. {
  15.   Geom *bbox;
  16.   bbox = GeomBound((Geom *)sphere, TM_IDENTITY);
  17.   BBoxMinMax((BBox *)bbox, min, max);
  18.   GeomDelete(bbox);
  19.   HPt3Normalize(min, min);
  20.   HPt3Normalize(max, max);
  21. }
  22.  
  23. void SphereCenter(Sphere *sphere, HPoint3 *center) 
  24. {
  25.   *center = sphere->center;
  26. }
  27.  
  28. float SphereRadius(Sphere *sphere) 
  29. {
  30.   return sphere->radius;
  31. }
  32.  
  33. void SphereSwitchSpace(Sphere *sphere, int space) {
  34.   Transform T;
  35.   
  36.   sphere->space = space;
  37.   TmScale(sphere->axis, sphere->radius, sphere->radius, sphere->radius);
  38.   TmSpaceTranslate(T, sphere->center.x, sphere->center.y, sphere->center.z,
  39.            sphere->space);
  40.   GeomTransform((Geom*)sphere, T);
  41. }
  42.  
  43. Sphere *SphereUnion3(Sphere *a, Sphere *b, Sphere *dest) {
  44.   Sphere *sphere;
  45.   int space;
  46.   HPoint3 center, diff;
  47.   float radius, mag_diff;
  48.  
  49.   if (a == NULL && b == NULL) return NULL;
  50.   space = (a != NULL) ? a->space : b->space;
  51.   if (dest == NULL) 
  52.     dest = (Sphere *)GeomCreate("sphere", CR_SPACE, space, CR_END);
  53.  
  54.   if (a == NULL || b == NULL) {
  55.     if (a == NULL) {
  56.       radius = b->radius;
  57.       center = b->center;
  58.       space = b->space;
  59.     }
  60.     else if (b == NULL) {
  61.       radius = a->radius;
  62.       center = a->center;
  63.       space = a->space;
  64.     } 
  65.     GeomSet((Geom*)dest, CR_RADIUS, radius, CR_CENTER, ¢er, CR_SPACE, space,
  66.         CR_END);
  67.   } else {
  68.   
  69.     if (a->space != b->space) 
  70.       OOGLError(1, "Uniting two spheres existing in different spaces.");
  71.     space = a->space;
  72.     if (space != TM_EUCLIDEAN)
  73.       OOGLError(1, "SphereUnion3 currently only works reliably in\n%s",
  74.         "Euclidean space.");
  75.     
  76.     HPt3Sub(&b->center, &a->center, &diff);
  77.     Pt3Unit((Point3*)&diff);
  78.     center.x = b->center.x + diff.x*b->radius;
  79.     center.y = b->center.y + diff.y*b->radius;
  80.     center.z = b->center.z + diff.z*b->radius;
  81.     center.w = 1.0;
  82.  
  83.     GeomSet((Geom*)dest, CR_RADIUS, a->radius, CR_CENTER, &a->center, CR_END);
  84.     SphereAddHPt3(dest, ¢er, TM_IDENTITY);
  85.   }
  86.  
  87.   return dest;
  88. }
  89.  
  90. void SphereEncompassBounds(Sphere *sphere, HPoint3 *points) {
  91.   int i, j;
  92.   float span, maxspan;
  93.   HPoint3 *d1, *d2, center;
  94.  
  95.  
  96.   d1 = d2 = &points[0];
  97.   maxspan = 0.0;
  98.   for (i = 0; i < 6; i++)
  99.     for (j = i+1; j < 6; j++) {
  100.       span = HPt3SpaceDistance(&points[i], &points[j], sphere->space);
  101.       if (span > maxspan) {
  102.     maxspan = span;
  103.     d1 = &points[i];
  104.     d2 = &points[j];
  105.       }
  106.     }
  107.   
  108.   /* Find the midpoint here - this will not work in non-Euclidean space */
  109.   center.x = (d1->x + d2->x) / 2.0;
  110.   center.y = (d1->y + d2->y) / 2.0;
  111.   center.z = (d1->z + d2->z) / 2.0;
  112.   center.w = 1.0;
  113.  
  114.   GeomSet((Geom *)sphere, CR_RADIUS, maxspan / 2.0, CR_CENTER, ¢er,
  115.       CR_END);
  116.  
  117. }
  118.             
  119. int SphereAddHPt3(Sphere *sphere, HPoint3 *point, Transform T)
  120. {
  121.   float radius, old_to_p, old_to_new;
  122.   Point3 direction;
  123.   HPoint3 center, newpoint;
  124.  
  125.   HPt3Transform(T, point, &newpoint);
  126.   old_to_p = HPt3SpaceDistance(&newpoint, &sphere->center, sphere->space);
  127.   if (old_to_p > sphere->radius) {
  128.     radius = (sphere->radius + old_to_p) / 2.0;
  129.     old_to_new = old_to_p - radius;
  130.     center.x = sphere->center.x + 
  131.       (newpoint.x - sphere->center.x)*old_to_new / old_to_p;
  132.     center.y = sphere->center.y + 
  133.       (newpoint.y - sphere->center.y)*old_to_new / old_to_p;
  134.     center.z = sphere->center.z + 
  135.       (newpoint.z - sphere->center.z)*old_to_new / old_to_p;
  136.     center.w = 1.0;
  137.     GeomSet((Geom *)sphere, CR_RADIUS, radius, CR_CENTER, ¢er, CR_END);
  138.     return 1;
  139.   } else return 0;
  140. }
  141.  
  142. int SphereAddHPt3N(Sphere *sphere, HPoint3 *point, int n, Transform T) 
  143. {
  144.   int i, ans = 0;
  145.  
  146.   for (i = 0; i < n; i++) ans |= SphereAddHPt3(sphere, &point[i], T);
  147.   return ans;
  148. }
  149.  
  150. void SphereEncompassHPt3N(Sphere *sphere, HPoint3 *point, int n,
  151.               Transform T) {
  152.   int i;
  153.   HPoint3 spanPts[6];
  154.  
  155.   if (!n) return;
  156.   for (i = 0; i < 6; i++) spanPts[i] = point[0];
  157.   MaxDimensionalSpanN(spanPts, point, n);
  158.   HPt3TransformN(T, spanPts, spanPts, 6);
  159.   SphereEncompassBounds(sphere, spanPts);
  160.   SphereAddHPt3N(sphere, point, n, T);
  161. }
  162.  
  163. /* 0 has min x, 1 has max x, 2 has min y... */
  164. void MaxDimensionalSpan(HPoint3 *spanPts, HPoint3 *point)
  165. {
  166.   if (point->x < spanPts[0].x) spanPts[0] = *point;
  167.   else if (point->x > spanPts[1].x) spanPts[1] = *point;
  168.   if (point->y < spanPts[2].y) spanPts[2] = *point;
  169.   else if (point->y > spanPts[3].y) spanPts[3] = *point;
  170.   if (point->z < spanPts[4].z) spanPts[4] = *point;
  171.   else if (point->z > spanPts[5].z) spanPts[5] = *point;
  172. }
  173.        
  174.  
  175. void MaxDimensionalSpanN(HPoint3 *spanPts, HPoint3 *points, int n) 
  176. {
  177.   int i;
  178.  
  179.   for (i = 0; i < n; i++) {
  180.     if (points[i].x < spanPts[0].x) spanPts[0] = points[i];
  181.     else if (points[i].x > spanPts[1].x) spanPts[1] = points[i];
  182.  
  183.     if (points[i].y < spanPts[2].y) spanPts[2] = points[i];
  184.     else if (points[i].y > spanPts[3].y) spanPts[3] = points[i];
  185.  
  186.     if (points[i].z < spanPts[4].z) spanPts[4] = points[i];
  187.     else if (points[i].z > spanPts[5].z) spanPts[5] = points[i];
  188.   }
  189. }
  190.